/**
 * Copyright 2013 ABSir's Studio
 * 
 * All right reserved
 *
 * Create on 2013-6-17 下午5:30:07
 */
package com.absir.bean.inject;

import com.absir.bean.basis.BeanDefine;
import com.absir.bean.basis.BeanScope;
import com.absir.bean.core.BeanDefineCloneable;
import com.absir.bean.core.BeanDefinePrototype;
import com.absir.bean.core.BeanDefineSingleton;
import com.absir.bean.core.BeanDefineSoftReference;
import com.absir.bean.core.BeanDefineWrapper;
import com.absir.bean.core.BeanFactoryImpl;
import com.absir.bean.inject.value.Bean;
import com.absir.core.kernel.KernelLang.CloneTemplate;

/**
 * @author absir
 * 
 */
public class InjectBeanDefine extends BeanDefineWrapper {

	/** beanScope */
	BeanScope beanScope;

	/** lazyInit */
	boolean lazyInit;

	/**
	 * @param beanDefine
	 */
	public InjectBeanDefine(BeanDefine beanDefine) {
		this(beanDefine, null);
	}

	/**
	 * @param beanDefine
	 * @param beanScope
	 */
	public InjectBeanDefine(BeanDefine beanDefine, Bean bean) {
		super(beanDefine);
		this.beanScope = beanScope == null ? BeanScope.SINGLETON : beanScope;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.absir.android.bean.value.IBeanDefine#getBeanObject()
	 */
	@Override
	public Object getBeanObject() {
		// TODO Auto-generated method stub
		BeanFactoryImpl beanFactory = (BeanFactoryImpl) getBeanFactory();
		if (beanScope == BeanScope.PROTOTYPE) {
			if (CloneTemplate.class.isAssignableFrom(beanDefine.getBeanType())) {
				if (!(beanDefine instanceof BeanDefineCloneable)) {
					beanDefine = new BeanDefineCloneable(getBeanName(), (CloneTemplate<?>) beanDefine.getBeanObject());
					beanFactory.registerBeanDefine(beanDefine);
				}

			} else if (!(beanDefine instanceof BeanDefinePrototype)) {
				beanDefine = new BeanDefinePrototype(beanDefine);
				beanFactory.registerBeanDefine(beanDefine);
			}

			return beanDefine.getBeanObject();

		} else {
			Object beanObject = beanDefine.getBeanObject();
			if (beanScope == BeanScope.SINGLETON || beanScope == BeanScope.LAZYINIT) {
				if (beanDefine instanceof BeanDefineSingleton) {
					return beanObject;
				}

				beanDefine = new BeanDefineSingleton(getBeanName(), beanObject);

			} else if (beanScope == BeanScope.SOFTREFERENCE) {
				if (beanDefine instanceof BeanDefineSoftReference) {
					return beanObject;
				}

				beanDefine = new BeanDefineSoftReference(getBeanName(), beanObject);
			}

			beanFactory.replaceRegisteredBeanDefine(beanDefine);
			beanFactory.processBeanObject(getBeanScope(), beanObject);
			return beanObject;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.absir.android.bean.BeanDefineWrapper#getBeanScope()
	 */
	@Override
	public BeanScope getBeanScope() {
		return beanScope;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.absir.android.bean.value.IBeanDefineWrapper#getBeanDefine(com.absir
	 * .android.bean.value.IBeanDefine)
	 */
	@Override
	public BeanDefine mergeBeanDefine(BeanDefine beanDefine) {
		// TODO Auto-generated method stub
		if (getBeanScope() == BeanScope.SINGLETON) {
			this.beanDefine = new BeanDefineWrapper(new BeanDefineSingleton(getBeanName(), beanDefine.getBeanObject()));

		} else if (getBeanScope() == BeanScope.SOFTREFERENCE) {
			this.beanDefine = new BeanDefineWrapper(new BeanDefineSoftReference(getBeanName(),
					beanDefine.getBeanObject()));

		} else if (CloneTemplate.class.isAssignableFrom(beanDefine.getBeanType())) {
			this.beanDefine = new BeanDefineCloneable(getBeanName(), (CloneTemplate<?>) beanDefine.getBeanObject());
		}

		return this;
	}
}
